package app.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Scroller;
import android.widget.TextView;
import app.log.APPLog;

import com.longevityassistant.activity.R;

/**
 * @author EX-LILI003
 * @date 2011-12-16
 * @version 1.0
 * @description 自定义ListView
 */
public class PullListView extends ListView {

    private static final String TAG = "PullToRefreshListView";
    
	/*
	 * 刷新状态
	 */
    public static final int STATE_REFRESH_IDEL = 1;
    public static final int STATE_PULL_TO_REFRESH = 2;
    public static final int STATE_RELEASE_TO_REFRESH = 3;
    public static final int STATE_REFRESHING = 4;
    private int mRefreshState;

    //ScrollView滑动状态
    
    private OnRefreshListener mOnRefreshListener;
    
    private LinearLayout mRefreshView;
    private TextView mRefreshViewText;
    private ImageView mRefreshViewImage;
    private ProgressBar mRefreshViewProgress;

    /*
     * 指示箭头动画
     */
    private RotateAnimation mFlipAnimation;
    private RotateAnimation mReverseFlipAnimation;

    private int mRefreshViewHeight;
    
    private Scroller mScroller;
	private boolean mIsAnimation;
	
	private int mMoreFooterCount;
	
	private boolean mIsSupportPull = true;
	
	private boolean mIsInit;
	
	private float mLastMotionY;
	
	private float mLastScrollY;
	
	//默认箭头
    private int mDefaulArrowResID = R.drawable.app_widget_arrow_loading_down;
    
    private boolean mIsRefresh;
    
    private boolean mIsFirstAddFooter;
    
    private boolean mIsAddFooter;
    
    public PullListView(Context context) {
        super(context);
        initList();
    }

    public PullListView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initList();
    }

    public PullListView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initList();
    }
    
    private void initList(){
    	mScroller = new Scroller(this.getContext(), new DecelerateInterpolator());
//		mScrollPaddingTask = new ScrollPaddingRunnable();

		RotateAnimation flipAnimation = new RotateAnimation(0, -180,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    	flipAnimation.setInterpolator(new LinearInterpolator());
    	flipAnimation.setDuration(200);
    	flipAnimation.setFillAfter(true);
        mFlipAnimation = flipAnimation;
        
        RotateAnimation reverseFlipAnimation = new RotateAnimation(-180, 0,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f,
                RotateAnimation.RELATIVE_TO_SELF, 0.5f);
        reverseFlipAnimation.setInterpolator(new LinearInterpolator());
        reverseFlipAnimation.setDuration(200);
        reverseFlipAnimation.setFillAfter(true);
        mReverseFlipAnimation = reverseFlipAnimation;
    }
    
    public void init() {
    	
    	if(!mIsInit && mIsSupportPull){
    		
    		Context context = this.getContext();
    		
	    	mMoreFooterCount = this.getFooterViewsCount();
	    	
	        LayoutInflater inflater = (LayoutInflater) context.getSystemService(
	                Context.LAYOUT_INFLATER_SERVICE);
	        LinearLayout refreshView = (LinearLayout) inflater.inflate(
					R.layout.app_widget_pull_to_refresh_view, this, false);
	        mRefreshViewText = (TextView) refreshView.findViewById(R.id.pull_refresh_text);
	        mRefreshViewImage = (ImageView) refreshView.findViewById(R.id.pull_refresh_image);
	        mRefreshViewProgress = (ProgressBar) refreshView.findViewById(R.id.pull_refresh_progress);
	        
	        if(mRefreshViewImage.getDrawable()==null){
	        	mRefreshViewImage.setImageResource(mDefaulArrowResID);
	        }
	        mRefreshViewImage.setMinimumHeight(50);
	        refreshView.setOnClickListener(null);
	        
	        this.addFooterView(refreshView);
	        mIsAddFooter = true;
	        
	        measureView(refreshView);
	        
	        mRefreshViewHeight = refreshView.getMeasuredHeight();
	        
	        APPLog.e(TAG, "mRefreshViewHeight:" + mRefreshViewHeight);
	        
	        mRefreshView = refreshView;
	        mRefreshState = STATE_REFRESH_IDEL;
	        
	        mIsInit = true;
    	}
    }

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		
		if (! mIsFirstAddFooter && mRefreshView != null) {
			this.removeFooterView(mRefreshView);
			mIsFirstAddFooter = true;
			mIsAddFooter = false;
		}
		APPLog.e(TAG, "onLayout");
	}

    public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
        mOnRefreshListener = onRefreshListener;
    }

	@Override
	public boolean onInterceptTouchEvent(MotionEvent ev) {
		this.requestDisallowInterceptTouchEvent(true);
		
		Log.i("debug", "onInterceptTouchEvent");
		return super.onInterceptTouchEvent(ev);
	}

	@Override
    public boolean onTouchEvent(MotionEvent event) {
		float touchY = event.getY(); 
		if(event.getAction()==MotionEvent.ACTION_MOVE){
			if(this.getFirstVisiblePosition()==0 &&
					touchY>mLastMotionY){
        		View firstChild = this.getChildAt(0);
        		if (firstChild != null) {
	            	int firstTop = firstChild.getTop();
	            	//事件上调,取消ListView事件
	            	if(firstTop==0){
	            		APPLog.i("debug", "ListView事件上传");
	            		this.requestDisallowInterceptTouchEvent(false);
	            		return true;
	            	}
        		}
        	} else if (! mIsSupportPull && this.getLastVisiblePosition() == this.getCount() - 1
        			&& touchY < mLastMotionY) {
        		View lastChild = this.getChildAt(this.getChildCount() -1 );
        		if (lastChild != null) {
	            	int lastBottom = lastChild.getBottom();
	            	if (lastBottom == this.getHeight()) {
	            		this.requestDisallowInterceptTouchEvent(false);
	            		return true;
	            	}
        		}
        	}
		}
		
		if (mIsSupportPull && mIsInit){
			
			if (!mScroller.isFinished()) {
                mScroller.abortAnimation();
            }
			
	        switch (event.getAction()) {
	            case MotionEvent.ACTION_UP:
	                if (!isVerticalScrollBarEnabled()) {
	                    setVerticalScrollBarEnabled(true);
	                }
	                
	                mLastScrollY = -1;

	                if (mRefreshView != null) {
		                if(mIsAnimation && mRefreshView.getPaddingBottom()>0){
		                	pullRefreshAnimation();
		                	break;
		                }
		
		                boolean isRefresh = false;
		                boolean isAborRefresh = false;
		                int refreshBottom = mRefreshView.getBottom();
		            	if (getLastVisiblePosition() == this.getCount()-1 
		            			&& mRefreshState != STATE_REFRESHING) {

		                    if (refreshBottom >= this.getHeight() &&
		                    		mIsAddFooter &&
		                            mRefreshState == STATE_RELEASE_TO_REFRESH) {
		                    	isRefresh = true;
		                    } else {
		                    	isAborRefresh = true;
		                    }
		                }
		                
		                if(isRefresh){
		                	//刷新数据
		                	APPLog.i(TAG, "ACTION_UP - prepareForRefresh");
		                	mRefreshState = STATE_REFRESHING;
		                    prepareForRefresh();
		                    onRefresh();
		                    
		                    pullRefreshAnimation();
		                    
		                }else if(isAborRefresh){
		                	//打断
		                	APPLog.i(TAG, "ACTION_UP - resetHeader");
		                	resetHeader();
		                }else if(this.getFooterViewsCount()>mMoreFooterCount
		                			&&  mRefreshState != STATE_REFRESHING){
		                	//超过界限则去除掉Footer
		                	APPLog.i(TAG, "ACTION_UP - resetPadding");
		                	mRefreshState = STATE_REFRESH_IDEL;
		                	resetPadding();
		                	mIsAddFooter = false;
		                	this.removeFooterView(mRefreshView);
		        		}
	                }
	                break;
	            case MotionEvent.ACTION_DOWN:
	                break;
	            case MotionEvent.ACTION_MOVE:
	            	onScroll(touchY);
	                break;
	        }
		}
		mLastMotionY = touchY;
        return super.onTouchEvent(event);
    }

	private void resetScrollPadding(){
		
		APPLog.e(TAG, "resetScrollPadding");
		mRefreshView.setPadding(
				mRefreshView.getPaddingLeft(), 
				mRefreshView.getPaddingTop(), 
				mRefreshView.getPaddingRight(), 
        		200);
	}
	
	
    /**
     * 重置刷新头部或底部边距
     * 
     * @return void
     * 
     */
    private void resetPadding() {
    		 
    	mIsAnimation = false;
    	if (mRefreshView != null) {
			mRefreshView.setPadding(
					mRefreshView.getPaddingLeft(),
					0,
	                mRefreshView.getPaddingRight(),
	                0);
    	}
    }

    private void resetHeader() {
        if (mRefreshState != STATE_REFRESH_IDEL) {
            mRefreshState = STATE_REFRESH_IDEL;

            if (mRefreshView != null) {
	            resetPadding();
	
	            mRefreshViewImage.setImageResource(mDefaulArrowResID);
	            mRefreshViewImage.clearAnimation();
	            mRefreshViewImage.setVisibility(View.GONE);
	            mRefreshViewProgress.setVisibility(View.GONE);
	            
	            if(this.getFooterViewsCount()>mMoreFooterCount) {
	            	this.removeFooterView(mRefreshView);
	            	mIsAddFooter = false;
	            }
            }
        }
    }

    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }

        int childWidthSpec = ViewGroup.getChildMeasureSpec(0,
                0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    private void onScroll(float touchY){
	    if (touchY < mLastMotionY || mRefreshState == STATE_RELEASE_TO_REFRESH) {
	    	APPLog.i(TAG, "onScroll 移动...");
	    	
	    	if (mRefreshState != STATE_REFRESHING 
	    			&& mRefreshView != null
	    			&& mIsInit) {
	    		
	    		int refreshState = mRefreshState;
	          	int refreshTop = mRefreshView.getTop();
	          	int lastVisibleItem = this.getLastVisiblePosition();
	          	int totalItemCount = this.getCount() - (this.getFooterViewsCount()-mMoreFooterCount) - 1;
	          	
	     		if (lastVisibleItem >= totalItemCount) {
	     			
	     			if(this.getFooterViewsCount()==mMoreFooterCount
	     					&& mLastScrollY > touchY){
	     				APPLog.i(TAG, "onScroll addFooterView()");
	         			this.addFooterView(mRefreshView);
	         			mIsAddFooter = true;
	         			resetScrollPadding();
	         		 }
	         		 
	         		 ImageView refreshImage = mRefreshViewImage;
	         		 TextView refreshText = mRefreshViewText;
	         		 refreshImage.setVisibility(View.VISIBLE);
	         		 
	     			int listHeight = this.getHeight();
	     			
	                if (refreshTop != 0
	                		&& refreshTop < listHeight
	                		&& refreshTop > listHeight - mRefreshViewHeight
	                        && refreshState != STATE_PULL_TO_REFRESH) {
	                	 
	                 	APPLog.e(TAG, "Pull ... ");
	                 	refreshText.setText(R.string.pull_load_more);
	                    if (refreshState != STATE_REFRESH_IDEL) {
	                    	refreshImage.clearAnimation();
	                    	refreshImage.startAnimation(mReverseFlipAnimation);
	                    }
	                    mRefreshState = STATE_PULL_TO_REFRESH;
	                }else if (refreshTop <= listHeight - mRefreshViewHeight
	                        && refreshState != STATE_RELEASE_TO_REFRESH) {
	                	
	                    APPLog.e(TAG, "Release ... ");
	                 	
	                 	refreshText.setText(R.string.pull_release_more);
	                 	refreshImage.clearAnimation();
	                 	refreshImage.startAnimation(mFlipAnimation);
	                 	mRefreshState = STATE_RELEASE_TO_REFRESH;
	                }
	     		}else {
	             	 APPLog.e(TAG, "Not VisibleRefresh");
	             	 mRefreshViewImage.setVisibility(View.GONE);
	                 resetHeader();
	     		 }
	         }
	    	  mLastScrollY = touchY;
    	}
    }
    
    public void setSupportPullMode(boolean isSupport){
    	this.mIsSupportPull = isSupport;
    	if(!isSupport){
    		if(mRefreshView!=null){
    			this.removeFooterView(mRefreshView);
    			mIsAddFooter = false;
    		}
    	}else{
    		//如果初始成功，但是mRefreshView没有被初始，则初始
    		if(mRefreshView==null){
    			init();
    		}
    	}
    }
    
    public void resetRefreshState() {
    	mRefreshState = STATE_REFRESH_IDEL;
    }
    
    public boolean getIsSupportPull(){
    	return this.mIsSupportPull;
    }

    /**
     * 刷新数据
     * 
     * @return void
     * 
     */
    public void prepareForRefresh() {
//        resetPadding();
    	
        mRefreshViewImage.setVisibility(View.GONE);
        mRefreshViewImage.setImageDrawable(null);
        mRefreshViewProgress.setVisibility(View.VISIBLE);

        mRefreshViewText.setText(R.string.pull_loading);

        mRefreshState = STATE_REFRESHING;
    }

    public void onRefresh() {
        APPLog.d(TAG, "onRefresh");
        mIsRefresh = true;
        if (mOnRefreshListener != null) {
            mOnRefreshListener.onRefresh();
        }
    }

    public void refresh() {        
        APPLog.d(TAG, "onRefreshComplete");

        mIsRefresh = false;
        resetHeader();
    }

    public interface OnRefreshListener {
        public void onRefresh();
    }
    
    public void pullRefreshAnimation(){
    	
    	mIsAnimation = true;
    	int paddingBottom = mRefreshView.getPaddingBottom();
    	mScroller.startScroll(0, paddingBottom, 0, -paddingBottom, 500);
    	this.invalidate();
    }
    
    public boolean isRefreshing() {
    	return mIsRefresh;
    }
    
    @Override
	public void computeScroll() {
    	
		 if (mScroller.computeScrollOffset()) {
			 
			int scrollY = mScroller.getCurrY();
			
			mRefreshView.setPadding(
					mRefreshView.getPaddingLeft(), 
					mRefreshView.getPaddingTop(), 
					mRefreshView.getPaddingRight(), 
					scrollY);
			
			if (mScroller.isFinished())
			{
				resetPadding();
			}
		}
	}
}